package day1.homework.two;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.RandomAccess;

/**
 * @创建人 MBY381
 * @创建时间 2022/6/27 15:42
 * @描述 暂无
 */
public class ArrayListCopy<E> implements RandomAccess {
    private final static int DEFAULT_CAPACITY = 10;
    private int size = 0;
    private Object[] elementData;
    private final static int MAX_ARRAY_LENGTH = Integer.MAX_VALUE - 8;


    public ArrayListCopy() {
        this(DEFAULT_CAPACITY);
    }

    ArrayListCopy(int size) {
        elementData = new Object[size];
    }


    //尾插
    public void add(E e) {
        checkCapacity(size + 1);
        elementData[size++] = e;
    }

    //指定位置插入
    public void add(int index, E e) {
        if (index < 0 || index > size) {
            throw new IndexOutOfBoundsException("指定的index超过界限");
        }
        checkCapacity(size + 1);
        System.arraycopy(elementData, index, elementData, index + 1, size - index);
        elementData[index] = e;
        size++;
    }

    //随机访问
    public E get(int index) {
        if (index >= size || index < 0) {
            throw new IndexOutOfBoundsException("指定的index不合法");
        }
        return (E) elementData[index];
    }


    //遍历
    public List<E> iterator() {
        List<E> list = new ArrayList<>();
        int tag = 0;
        while (tag < size && elementData[tag] != null) {
            list.add((E) elementData[tag]);
            tag++;
        }
        return list;
    }

    //下标查找
    public int indexOf(Object o) {
        if (o != null) {
            for (int i = 0; i < size; i++) {
                if (o.equals(elementData[i])) {
                    return i;
                }
            }
        } else {
            for (int i = 0; i < size; i++) {
                if (elementData[i] == null) {
                    return i;
                }
            }
        }

        return -1;
    }




    //无关方法

    @Override
    public String toString(){
        return Arrays.toString(Arrays.copyOf(elementData,size));
    }

    private void explicitCapacity(int capacity) {
        int newLength = elementData.length * 2;
        if (newLength - capacity < 0) {
            newLength = capacity;
        }
        if (newLength > (MAX_ARRAY_LENGTH)) {
            newLength = (capacity > MAX_ARRAY_LENGTH ? Integer.MAX_VALUE : MAX_ARRAY_LENGTH);
        }
        elementData = Arrays.copyOf(elementData, newLength);
    }


    public boolean contains(Object o) {
        return indexOf(o) >= 0;
    }

    public int size() {
        return size;
    }

    public boolean isEmpty() {
        return size() == 0;
    }


    public E remove(int index) {
        E value = get(index);
        int moveSize = size - index - 1;
        if (moveSize > 0) {
            System.arraycopy(elementData, index + 1, elementData, index, size - index - 1);
        }
        elementData[--size] = null;
        return value;
    }


    public boolean remove(Object o) {
        if (contains(o)) {
            remove(indexOf(o));
            return true;
        } else {
            return false;
        }
    }

    private void checkCapacity(int size) {
        if (size > DEFAULT_CAPACITY) {
            explicitCapacity(size);
        }
        if (size < 0) {
            throw new OutOfMemoryError();
        }
    }


}